using UnityEngine;
using System.IO;
using LitJson;
using System.Text.RegularExpressions;
using System;
using Newtonsoft.Json;

/// <summary>
/// //Json读写
/// </summary>
public class JsonIO
{
    public enum JsonAnalysisType
    {
        LitJson,
        NewtonSoftJson,
    }

    /// <summary>
    /// 从Resources文件夹读取JSON文件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="jsonFileName">JSON文件的名字</param>
    /// <returns></returns>
    static public T LoadJsonFromResourcesFile<T>(string jsonFileName, JsonAnalysisType type = JsonAnalysisType.LitJson)
    {
        TextAsset text = Resources.Load<TextAsset>("Json/" + jsonFileName) as TextAsset;
        string json = text.text;

        if (string.IsNullOrEmpty(json))
            return default;

        //读取Json文件.
        //根据使用的数据类型<T>值可以是任何类型.相应返回值做一些修改即可
        return DeserializeObject<T>(json, type);
    }

    /// <summary>
    /// 从指定路径读取JSON文件
    /// </summary>
    /// <param name="jsonPath">JSON文件的路径</param>
    /// <returns></returns>
    static public T LoadJsonFromFile<T>(string jsonPath, JsonAnalysisType type = JsonAnalysisType.LitJson)
    {
        if (!File.Exists(jsonPath))
        {
            Debug.Log($"路径不存在:{jsonPath}");
            return default;
        }

        T data = DeserializeObject<T>(File.ReadAllText(jsonPath), type);

        return data;
    }

    /// <summary>
    /// 输出Json文件到指定目录
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="dataList"></param>
    /// <param name="path"></param>
    static public void ExportJsonToFile<T>(T dataList, string path, JsonAnalysisType type = JsonAnalysisType.LitJson)
    {
        string jsonStr = SerializeObject(dataList, type);
        //将json中部分Unicode转成中文
        Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");//正则表达式规定格式
        jsonStr = reg.Replace(jsonStr,
        delegate (Match m)
        {
            return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString();
        });
        if (!File.Exists(path)) // 判断是否已有相同文件 
        {
            FileStream fs1 = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);
            fs1.Close();
        }
        File.WriteAllText(path, jsonStr, System.Text.Encoding.UTF8);
    }

    /// <summary>
    /// 序列化成Json
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    static public string LoadObjToJson<T>(T obj, JsonAnalysisType type = JsonAnalysisType.LitJson)
    {
        //读取对象
        //根据使用的数据类型<T>值可以是任何类型.相应返回值做一些修改即可.非常方便.
        return SerializeObject(obj, type);
    }

    /// <summary>
    /// 反序列化成对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="json"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    static public T LoadJsonToObj<T>(string json, JsonAnalysisType type = JsonAnalysisType.LitJson)
    {
        return DeserializeObject<T>(json, type);
    }

    /// <summary>
    /// 序列化成Json字符串
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    static private string SerializeObject<T>(T obj, JsonAnalysisType type)
    {
        switch (type)
        {
            case JsonAnalysisType.LitJson:
                return JsonMapper.ToJson(obj);
            case JsonAnalysisType.NewtonSoftJson:
                var settings = new JsonSerializerSettings
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    // 忽略只读属性，比如 normalized / magnitude / sqrMagnitude
                    ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver
                    {
                        IgnoreSerializableInterface = true
                    }
                };
                return Newtonsoft.Json.JsonConvert.SerializeObject(obj, settings);
            default:
                return Newtonsoft.Json.JsonConvert.SerializeObject(obj);
        }
    }

    /// <summary>
    /// 反序列化成对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="type"></param>
    /// <returns></returns>
    static private T DeserializeObject<T>(string json, JsonAnalysisType type)
    {
        switch (type)
        {
            case JsonAnalysisType.LitJson:
                return JsonMapper.ToObject<T>(json);
            case JsonAnalysisType.NewtonSoftJson:
                return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
            default:
                return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
        }
    }
}

